import cloneDeep from 'lodash/cloneDeep'
import {login, logout, getInfo} from '@/api/user'
import {getToken, setToken, removeToken} from '@/utils/auth'
import router, {resetRouter} from '@/router'
import {constantRoutes, allAsyncRoutes, anyRoute} from "@/router/routes";

//对所有的异步路由进行权限过滤,得到当前用户对应的异步路由
function filterAsyncRoutes(allAsyncRoutes, routeNames) {
  return allAsyncRoutes.filter(route => {
    //如果route的name没有在routeNames中, 直接过滤掉
    if (!routeNames.includes(route.name)) return false
    //进一步去过滤内部的子路由
    if (route.children && route.children.length) {//有子路由
      //注意这个会改变allAsyncRoutes数组内部的数据
      route.children = filterAsyncRoutes(route.children, routeNames)
    }
    return true
  })
}

const getDefaultState = () => {
  return {
    token: getToken(),
    name: '',
    avatar: '',
    //权限相关数组
    roles: [],//对应角色名的角色
    routes: [],//用于显示菜单异步的路由配置的数组
    buttons: []//按钮权限表示名称的数组
  }
}

const state = getDefaultState()

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  },
  SET_USER(state, {name, avatar, roles, buttons}) {
    state.name = name
    state.avatar = avatar
    state.roles = roles
    state.buttons = buttons
  },
  SET_ROUTES(state, asyncRoutes) {
    //将常量路由与异步路由进行合并并保存
    state.routes = constantRoutes.concat(asyncRoutes)
    //动态路由添加/注册异步路由
    router.addRoutes(asyncRoutes.concat(anyRoute))
  }
}

const actions = {
  // user login
  login({commit}, userInfo) {
    const {username, password} = userInfo
    return new Promise((resolve, reject) => {
      login({username: username.trim(), password: password}).then(response => {
        const {data} = response
        commit('SET_TOKEN', data.token)
        setToken(data.token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // get user info
  async getInfo({commit, state}) {
    const {data} = await getInfo()
    if (!data) {
      return this.$message.error('Verification failed, please Login again.')
    }
    const {name, avatar, roles, buttons, routes} = data
    commit('SET_USER', {name, avatar, roles, buttons})
    commit('SET_ROUTES', filterAsyncRoutes(cloneDeep(allAsyncRoutes), routes))
    return data
  },
  async resetUser({commit, state}) {
    if (state.name){
      await logout()
    }
    removeToken()//删除保存的token
    resetRouter()//重置路由
    commit('RESET_STATE')//重置用户信息
  },
  // user logout
  // logout({commit, state}) {
  //   return new Promise((resolve, reject) => {
  //     logout(state.token).then(() => {
  //       removeToken() // must remove  token  first
  //       resetRouter()
  //       commit('RESET_STATE')
  //       resolve()
  //     }).catch(error => {
  //       reject(error)
  //     })
  //   })
  // },

  //remove token
  resetToken({commit}) {
    return new Promise(resolve => {
      removeToken() // must remove  token  first
      commit('RESET_STATE')
      resolve()
    })
  }
}

export default {
  namespaced: true,//开启命名空间
  state,
  mutations,
  actions
}

